package com.chensi.admin.web.util;


import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class HttpUtils {
    public static String doPost(final String url, Map<String, String> params, Map<String, String> headers, Map<String, ?> body) {
        HttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);

        if (params != null && params.keySet().size() > 0) {
            String paramsStr = "";
            for (String key : params.keySet()) {
                if (paramsStr.equals("")) {
                    paramsStr = key + "=" + URLEncoder.encode(params.get(key));
                } else {
                    paramsStr = paramsStr + "&" + key + "=" + URLEncoder.encode(params.get(key));
                }
                httpPost = new HttpPost(url + "?" + paramsStr);
            }
        }

        if (headers != null && headers.keySet().size() > 0) {
            for (String key : headers.keySet()) {
                httpPost.setHeader(key, headers.get(key));
            }
        }

        StringEntity stringEntity = new StringEntity(JsonUtil.jsonObj2Sting(body), "UTF-8");
        httpPost.setEntity(stringEntity);

        HttpResponse response;
        String responseStr;
        try {
            response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            responseStr = EntityUtils.toString(entity, "UTF-8");
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            return "httputils call" + url + "fail";
        } catch (IOException e) {
            e.printStackTrace();
            return "httputils call" + url + "fail";
        }

        return responseStr;
    }

    public static String doPost(final String url, final List<NameValuePair> nameValuePairList) throws IOException {
        String body;
        final HttpClient httpClient = HttpClients.createDefault();
        final HttpPost httpPost = new HttpPost();
        httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairList));
        try {
            final HttpResponse httpResponse = httpClient.execute(httpPost);
            final HttpEntity httpEntity = httpResponse.getEntity();
            body = EntityUtils.toString(httpEntity);
        } finally {
            httpClient.getConnectionManager().shutdown();
        }
        return body;
    }

    public static String doPost(final String url, final Map<String, ?> map) throws IOException {
        final String jsonStr = JsonUtil.jsonObj2Sting(map);
        return doPost(url, jsonStr);

    }

    @SuppressWarnings("deprecation")
    public static String doPost(final String url, final String json) throws IOException {
        String body;
        final CloseableHttpClient httpClient = HttpClients.createDefault();
        try {
            final HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
            final StringEntity stringEntity = new StringEntity(json, StandardCharsets.UTF_8);
            stringEntity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
            httpPost.setEntity(stringEntity);
            final HttpResponse response = httpClient.execute(httpPost);
            final HttpEntity entity = response.getEntity();
            body = EntityUtils.toString(entity);
        } finally {
            httpClient.getConnectionManager().shutdown();
        }
        return body;
    }

    /**
     * 封装HTTP GET方法
     * 有参数的Get请求
     *
     * @param
     * @param
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String doGet(String url, Map<String, String> paramMap) throws ClientProtocolException, IOException {
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet();
        List<NameValuePair> formparams = setHttpParams(paramMap);
        String param = URLEncodedUtils.format(formparams, "UTF-8");
        httpGet.setURI(URI.create(url + "?" + param));
        HttpResponse response = httpClient.execute(httpGet);
        String httpEntityContent = getHttpEntityContent(response);
        httpGet.abort();
        return httpEntityContent;
    }

    /**
     * 设置请求参数
     *
     * @param
     * @return
     */
    private static List<NameValuePair> setHttpParams(Map<String, String> paramMap) {
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        Set<Map.Entry<String, String>> set = paramMap.entrySet();
        for (Map.Entry<String, String> entry : set) {
            formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        return formparams;
    }

    private static String getHttpEntityContent(HttpResponse response) throws IOException, UnsupportedEncodingException {
        //通过HttpResponse 的getEntity()方法获取返回信息
        HttpEntity entity = response.getEntity();
        if (entity == null) {
            return "";
        }

        InputStream is = entity.getContent();
        BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        String line = br.readLine();
        StringBuilder sb = new StringBuilder();
        while (line != null) {
            sb.append(line + "\n");
            line = br.readLine();
        }
        br.close();
        is.close();
        return sb.toString();
    }


    /**
     * 设置URLConnection通用属性
     *
     * @param conn
     */
    private static void setURLConnection(URLConnection conn) {
        //设置通用的请求属性
        conn.setRequestProperty("Accept", "*/*");
        conn.setRequestProperty("Cache-Control", "max-age=0");
        conn.setRequestProperty("Connection", "keep-alive");
        conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36");
        conn.setRequestProperty("transfer-encoding", "chunked");
        conn.setRequestProperty("Accept-Encoding", "gzip, deflate, br");

        conn.setRequestProperty("Content-Type", "text/html;charset=UTF-8;application/x-java-serialized-object;application/stream");
    }

    /**
     * @param charset 编码格式，可以为空
     * @param url     访问url 不带问号
     * @param params  get请求需要的参数 name=value&name&value
     * @return 请求结果
     * @Author: 屈想顺
     * @Date: Created in 11:07 2018/10/21
     * @Description: 发送Get请求
     */
    public static String sendGet(String charset, String url, String params) {
        String result = "";
        BufferedReader in = null;
        try {
            if (params != null) {
                url = url + "?" + params;
            }

            URL realUrl = new URL(url);
            //打开链接
            URLConnection conn = realUrl.openConnection();
            //设置URLConnection通用属性
            setURLConnection(conn);
            //建立实际链接
            conn.connect();
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset));

            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

}
